package com.atguigu.gmall.common.config.mq;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.MD5;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
@Slf4j
public class MqService {

    private StringRedisTemplate redisTemplate;

    private RabbitTemplate rabbitTemplate;

    public MqService(RabbitTemplate rabbitTemplate,StringRedisTemplate redisTemplate){
        this.rabbitTemplate = rabbitTemplate;
        this.redisTemplate = redisTemplate;
        initTemplate();
    }

    public void send(Object message,String exchange,String routingKey){
        rabbitTemplate.convertAndSend(exchange,routingKey, JSON.toJSONString(message));
    }
    private void initTemplate() {
        this.rabbitTemplate.setConfirmCallback( (CorrelationData var1, boolean ack, String cause)->{
            log.info("Confirm回调：CorrelationData:{},ack:{},cause:{}",var1,ack,cause);
        });
        this.rabbitTemplate.setReturnCallback((Message message, int replyCode, String replyText, String exchange, String routingKey)->{
            log.info("Return回调：message:{},replyCode:{},replyText:{},exchange:{},routingKey:{}",message,replyCode,replyText,exchange,routingKey);
        });
        //重试器
        rabbitTemplate.setRetryTemplate(new RetryTemplate());
    }
    /**
     * 重试次数设置
     *
     * @param channel：链接属性
     * @param deliveryTag：分发的标签
     * @param content：队列的数据
     * @param retryCount:重试次数
     * @throws IOException
     */
    public void retry(Channel channel, long deliveryTag, String content, Integer retryCount) throws IOException {
        String encrypt = MD5.encrypt(content);
        Long increment = redisTemplate.opsForValue().increment(RedisConst.MSG_COUNT + encrypt);
        if (increment <= retryCount){
            log.error("消费重试次数，{}",increment);
            channel.basicNack(deliveryTag,false,true);
        }else {
            log.error("消费重试超过组大次数，{}",increment);
            channel.basicNack(deliveryTag,false,false);
        }
    }

}
